package com.scpii.api.common.auth;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;

import com.scpii.api.common.Constants;

public class DefaultAuthorizationRequest implements AuthorizationRequest,
		Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6521192213585837908L;

	private Map<String, String> authorizationParameters = new HashMap<String, String>();

	private Collection<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();

	private boolean approved = false;

	public DefaultAuthorizationRequest(
			Map<String, String> authorizationParameters) {
		this(authorizationParameters, authorizationParameters.get(APP_ID),
				authorizationParameters.get(DEVICE_ID), null, false);
	}

	public DefaultAuthorizationRequest(
			Map<String, String> authorizationParameters, String clientId,
			String deviceId) {
		this(authorizationParameters, clientId, deviceId, null, false);
	}

	public DefaultAuthorizationRequest(AuthorizationRequest copy) {
		this(copy.getAuthorizationParameters(), copy.getAppId(), copy
				.getDeviceId(), copy.getAuthorities(), copy.isApproved());
	}

	private DefaultAuthorizationRequest(
			Map<String, String> authorizationParameters, String clientId,
			String deviceId, Collection<GrantedAuthority> authorities,
			boolean approved) {
		if (authorizationParameters != null) {
			this.authorizationParameters.putAll(authorizationParameters);
		}
		if (authorities != null) {
			this.authorities = new HashSet<GrantedAuthority>(authorities);
		}
		this.authorizationParameters.put(APP_ID, clientId);
		this.approved = approved;
	}

	@Override
	public String getAppId() {
		return authorizationParameters.get(APP_ID);
	}

	@Override
	public Collection<GrantedAuthority> getAuthorities() {
		return Collections
				.unmodifiableSet((Set<? extends GrantedAuthority>) authorities);
	}

	public void addClientAuthorities() {
		authorities.addAll(AuthorityUtils
				.commaSeparatedStringToAuthorityList(Constants.ROLES
						.get("ROLE_CLIENT")));
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((authorizationParameters == null) ? 0
						: authorizationParameters.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		DefaultAuthorizationRequest other = (DefaultAuthorizationRequest) obj;
		if (authorizationParameters == null) {
			if (other.authorizationParameters != null)
				return false;
		} else if (!authorizationParameters
				.equals(other.authorizationParameters))
			return false;
		return true;
	}

	@Override
	public boolean isApproved() {
		return approved;
	}

	public void setApproved(boolean approved) {
		this.approved = approved;
	}

	@Override
	public Map<String, String> getAuthorizationParameters() {
		return Collections.unmodifiableMap(authorizationParameters);

	}

	@Override
	public String getDeviceId() {
		return authorizationParameters.get(DEVICE_ID);
	}

}
